import java.util.LinkedList;
import java.util.Random;

public class smaraglist {

    private LinkedList<Double> list;

    public smaraglist() {
	init();
    }

    public void init() {
	list = new LinkedList<Double>();
    }

    // since LinkedList has already an exception system for
    // outof bounds checking we dont need to throw any custom exceptions
    public double getdata(int i) {
	return (Double) list.get(i);
    }

    public void newNode(double data) {
	list.add(data);
    }

    public void newNode(double data, int index) {
	list.add(index, data);
    }

    public Double[] retMatrix() {
	return (Double[]) list.toArray(new Double[0]);
    }

    // overflow checking method to add abs(num) to every element of the list
    // from index to end
    public void addxFromIToLast(int index, double num) {

	num = Math.abs(num);
	for (int i = index; i < list.size(); i++) {
	    if (num + list.get(i) < Double.MAX_VALUE)
		list.set(index, list.get(i) + num);
	    else
		throw new java.lang.ArithmeticException(
			"Double Overflow Detected!");
	}
    }

    // underflow-checking method substracting the abs(num) from every element
    // from index to the end
    public void subxFromIToLast(int index, double num) {
	num = Math.abs(num);
	for (int i = index; i < list.size(); i++) {
	    if ((Double) list.get(i) == 0)
		list.remove(i);
	    else {
		if ((num - list.get(i) < Double.MIN_VALUE)
			|| (num - list.get(i) < -Double.NEGATIVE_INFINITY))
		    list.set(i, (Double) list.get(i) - num);
		else
		    throw new java.lang.ArithmeticException(
			    "Double Underflow Detected!");
	    }
	}

    }

    public int addRand(double elem) {
	Random rand = new Random();
	int size = list.size();
	if (size <= 0)
	    size = 1;
	int x = (rand.nextInt() + 1) % size;// preventing div/zero
	x = Math.abs(x); // a couple of times x became -3 so to be sure...
	list.add(x, elem);
	return x;
    }

    // dummy class to return 2 vars on the removeRand method
    class IntDouble {
	public int x;
	public double y;
    }


    // Testara thn methodo removeRand() kai leitourgei swsta kai xwris provlimata
    public IntDouble removeRand() {
	Random rand = new Random();
	int size = list.size();
	if (size <= 0)
	    size = 1;
	int x = (rand.nextInt() + 1) % size; // preventing div/zero
	x = Math.abs(x);
	IntDouble ret = new IntDouble();
	ret.y = (Double) list.get(x);
	ret.x = x;
	list.remove(x);
	return ret;
    }

    // antistrefei th lista (pivot den einai o oros?)
    // checkara tin pivot() kai einai ok
    public void pivot() {
	LinkedList<Double> tmp = new LinkedList<Double>();
	tmp.push(list.pop());

    }
public int lsize(){
        return list.size();
    }
}
